package org.ibase4j.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.ibase4j.core.Constants;
import org.ibase4j.core.base.BaseService;
import org.ibase4j.core.util.InstanceUtil;
import org.ibase4j.mapper.PlatProAuthorizeMapper;
import org.ibase4j.mapper.PlatProRoleMenuMapper;
import org.ibase4j.mapper.PlatProUserMenuMapper;
import org.ibase4j.mapper.PlatProUserRoleMapper;
import org.ibase4j.model.PlatProDic;
import org.ibase4j.model.PlatProMenu;
import org.ibase4j.model.PlatProRoleMenu;
import org.ibase4j.model.PlatProUserMenu;
import org.ibase4j.model.PlatProUserRole;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;

/**
 * @author ShenHuaJie
 * @version 2016年5月20日 下午3:19:19
 */
@Service
@CacheConfig(cacheNames = "PlatAuthorize")
public class PlatProAuthorizeService extends BaseService<PlatProMenu> {
	@Autowired
	private PlatProUserMenuMapper platProUserMenuMapper;
	@Autowired
	private PlatProUserRoleMapper platProUserRoleMapper;
	@Autowired
	private PlatProRoleMenuMapper platProRoleMenuMapper;
	@Autowired
	private PlatProAuthorizeMapper platProAuthorizeMapper;
	@Autowired
	private PlatProMenuService platProMenuService;
	@Autowired
	private PlatProDicService platProDicService;

	public List<String> queryMenuIdsByUserId(Long userId) {
		List<String> resultList = InstanceUtil.newArrayList();
		List<Long> list = platProUserMenuMapper.queryMenuIdsByUserId(userId);
		for (Long id : list) {
			resultList.add(id.toString());
		}
		return resultList;
	}

	@Transactional
	@CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
			Constants.CACHE_NAMESPACE + "userPermission" }, allEntries = true)
	public void updateUserMenu(List<PlatProUserMenu> platProUserMenus) {
		Long userId = null;
		for (PlatProUserMenu platProUserMenu : platProUserMenus) {
			if (platProUserMenu != null && platProUserMenu.getUserId() != null && "read".equals(platProUserMenu.getPermission())) {
				userId = platProUserMenu.getUserId();
			}
		}
		if (userId != null) {
			platProAuthorizeMapper.deleteUserMenu(userId, "read");
		}
		for (PlatProUserMenu platProUserMenu : platProUserMenus) {
			if (platProUserMenu != null && platProUserMenu.getUserId() != null && platProUserMenu.getMenuId() != null
					&& "read".equals(platProUserMenu.getPermission())) {
				platProUserMenuMapper.insert(platProUserMenu);
			}
		}
	}

	@Transactional
	@CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
			Constants.CACHE_NAMESPACE + "userPermission" }, allEntries = true)
	public void updateUserPermission(List<PlatProUserMenu> platProUserMenus) {
		Long userId = null;
		for (PlatProUserMenu platProUserMenu : platProUserMenus) {
			if (platProUserMenu != null && platProUserMenu.getUserId() != null) {
				userId = platProUserMenu.getUserId();
				break;
			}
		}
		if (userId != null) {
			Map<String, Object> dicParam = InstanceUtil.newHashMap();
			dicParam.put("type", "CRUD");
			List<PlatProDic> platProDics = platProDicService.queryList(dicParam);
			for (PlatProDic platProDic : platProDics) {
				if (platProDic != null && !"read".equals(platProDic.getCode())) {
					platProAuthorizeMapper.deleteUserMenu(userId, platProDic.getCode());
				}
			}
		}
		for (PlatProUserMenu platProUserMenu : platProUserMenus) {
			if (platProUserMenu != null && platProUserMenu.getUserId() != null && platProUserMenu.getMenuId() != null
					&& !"read".equals(platProUserMenu.getPermission())) {
				platProUserMenuMapper.insert(platProUserMenu);
			}
		}
	}

	public List<PlatProUserRole> getRolesByUserId(Long userId) {
		PlatProUserRole platProUserRole = new PlatProUserRole(userId, null);
		Wrapper<PlatProUserRole> wrapper = new EntityWrapper<PlatProUserRole>(platProUserRole);
		List<PlatProUserRole> userRoles = platProUserRoleMapper.selectList(wrapper);
		return userRoles;
	}

	@Transactional
	@CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
			Constants.CACHE_NAMESPACE + "userPermission",
			Constants.CACHE_NAMESPACE + "rolePermission" }, allEntries = true)
	public void updateUserRole(List<PlatProUserRole> platProUserRoles) {
		Long userId = null;
		for (PlatProUserRole platProUserRole : platProUserRoles) {
			if (platProUserRole != null && platProUserRole.getUserId() != null) {
				userId = platProUserRole.getUserId();
				break;
			}
		}
		if (userId != null) {
			platProAuthorizeMapper.deleteUserRole(userId);
		}
		for (PlatProUserRole platProUserRole : platProUserRoles) {
			if (platProUserRole != null && platProUserRole.getUserId() != null && platProUserRole.getRoleId() != null) {
				platProUserRoleMapper.insert(platProUserRole);
			}
		}
	}

	public List<String> queryMenuIdsByRoleId(Long roleId) {
		List<String> resultList = InstanceUtil.newArrayList();
		List<Long> list = platProRoleMenuMapper.queryMenuIdsByRoleId(roleId);
		for (Long id : list) {
			resultList.add(id.toString());
		}
		return resultList;
	}

	@Transactional
	@CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
			Constants.CACHE_NAMESPACE + "userPermission",
			Constants.CACHE_NAMESPACE + "rolePermission" }, allEntries = true)
	public void updateRoleMenu(List<PlatProRoleMenu> platProRoleMenus) {
		Long roleId = null;
		for (PlatProRoleMenu platProRoleMenu : platProRoleMenus) {
			if (platProRoleMenu != null && platProRoleMenu.getRoleId() != null && "read".equals(platProRoleMenu.getPermission())) {
				roleId = platProRoleMenu.getRoleId();
				break;
			}
		}
		if (roleId != null) {
			platProAuthorizeMapper.deleteRoleMenu(roleId, "read");
		}
		for (PlatProRoleMenu platProRoleMenu : platProRoleMenus) {
			if (platProRoleMenu != null && platProRoleMenu.getRoleId() != null && platProRoleMenu.getMenuId() != null
					&& "read".equals(platProRoleMenu.getPermission())) {
				platProRoleMenuMapper.insert(platProRoleMenu);
			}
		}
	}

	@Transactional
	@CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
			Constants.CACHE_NAMESPACE + "userPermission",
			Constants.CACHE_NAMESPACE + "rolePermission" }, allEntries = true)
	public void updateRolePermission(List<PlatProRoleMenu> platProRoleMenus) {
		Long roleId = null;
		for (PlatProRoleMenu platProRoleMenu : platProRoleMenus) {
			if (platProRoleMenu != null && platProRoleMenu.getRoleId() != null) {
				roleId = platProRoleMenu.getRoleId();
			}
		}
		if (roleId != null) {
			Map<String, Object> dicParam = InstanceUtil.newHashMap();
			dicParam.put("type", "CRUD");
			List<PlatProDic> platProDics = platProDicService.queryList(dicParam);
			for (PlatProDic platProDic : platProDics) {
				if (platProDic != null && !"read".equals(platProDic.getCode())) {
					platProAuthorizeMapper.deleteRoleMenu(roleId, platProDic.getCode());
				}
			}
		}
		for (PlatProRoleMenu platProRoleMenu : platProRoleMenus) {
			if (platProRoleMenu != null && platProRoleMenu.getRoleId() != null && platProRoleMenu.getMenuId() != null
					&& !"read".equals(platProRoleMenu.getPermission())) {
				platProRoleMenuMapper.insert(platProRoleMenu);
			}
		}
	}

	@Cacheable(value = Constants.CACHE_NAMESPACE + "menuPermission")
	public List<PlatProMenu> queryAuthorizeByUserId(Long userId) {
		List<Long> menuIds = platProAuthorizeMapper.getAuthorize(userId);
		List<PlatProMenu> menus = platProMenuService.getList(menuIds);
		Map<Long, List<PlatProMenu>> map = InstanceUtil.newHashMap();
		for (PlatProMenu platProMenu : menus) {
			if (platProMenu != null && map.get(platProMenu.getParentId()) == null) {
				List<PlatProMenu> menuBeans = InstanceUtil.newArrayList();
				map.put(platProMenu.getParentId(), menuBeans);
			}
			map.get(platProMenu.getParentId()).add(platProMenu);
		}
		List<PlatProMenu> result = InstanceUtil.newArrayList();
		for (PlatProMenu platProMenu : menus) {
			if (platProMenu != null && platProMenu.getParentId() == null || platProMenu.getParentId() == 0) {
				platProMenu.setLeaf(0);
				platProMenu.setMenuBeans(getChildMenu(map, platProMenu.getId()));
				result.add(platProMenu);
			}
		}
		return result;
	}

	// 递归获取子菜单
	private List<PlatProMenu> getChildMenu(Map<Long, List<PlatProMenu>> map, Long id) {
		List<PlatProMenu> menus = map.get(id);
		if (menus != null) {
			for (PlatProMenu platProMenu : menus) {
				if (platProMenu != null) {
					platProMenu.setMenuBeans(getChildMenu(map, platProMenu.getId()));
				}
			}
		}
		return menus;
	}

	@Cacheable(Constants.CACHE_NAMESPACE + "sysPermission")
	public List<String> queryPermissionByUserId(Long userId) {
		return platProAuthorizeMapper.queryPermissionByUserId(userId);
	}
	public List<String> queryRoleByUserId(Long userId){
		return platProAuthorizeMapper.queryRoleByUserId(userId);
	}

	@Cacheable(Constants.CACHE_NAMESPACE + "userPermission")
	public List<String> queryUserPermission(Long userId) {
		return platProUserMenuMapper.queryPermission(userId);
	}

	@Cacheable(Constants.CACHE_NAMESPACE + "rolePermission")
	public List<String> queryRolePermission(Long roleId) {
		return platProRoleMenuMapper.queryPermission(roleId);
	}

	public List<PlatProMenu> queryMenusPermission() {
		return platProAuthorizeMapper.queryMenusPermission();
	}

	public List<Map<String, Object>> queryUserPermissions(PlatProUserMenu platProUserMenu) {
		List<Map<String, Object>> list = platProUserMenuMapper.queryPermissions(platProUserMenu.getUserId());
		return list;
	}

	public List<Map<String, Object>> queryRolePermissions(PlatProRoleMenu platProRoleMenu) {
		List<Map<String, Object>> list = platProRoleMenuMapper.queryPermissions(platProRoleMenu.getRoleId());
		return list;
	}
}
